// 性能监控工具
export interface PerformanceMetric {
  name: string
  value: number
  unit: string
  timestamp: number
}

export class PerformanceMonitor {
  private static instance: PerformanceMonitor
  private metrics: PerformanceMetric[] = []
  private observers: PerformanceObserver[] = []

  static getInstance(): PerformanceMonitor {
    if (!PerformanceMonitor.instance) {
      PerformanceMonitor.instance = new PerformanceMonitor()
    }
    return PerformanceMonitor.instance
  }

  // 初始化性能监控
  init(): void {
    this.observeNavigationTiming()
    this.observeResourceTiming()
    this.observeLCP()
    this.observeFID()
    this.observeCLS()
  }

  // 监控导航时间
  private observeNavigationTiming(): void {
    if ('performance' in window && 'getEntriesByType' in performance) {
      const navigationEntries = performance.getEntriesByType('navigation') as PerformanceNavigationTiming[]
      
      if (navigationEntries.length > 0) {
        const entry = navigationEntries[0]
        
        this.recordMetric('DNS查询时间', entry.domainLookupEnd - entry.domainLookupStart, 'ms')
        this.recordMetric('TCP连接时间', entry.connectEnd - entry.connectStart, 'ms')
        this.recordMetric('请求响应时间', entry.responseEnd - entry.requestStart, 'ms')
        this.recordMetric('DOM解析时间', entry.domContentLoadedEventEnd - entry.domContentLoadedEventStart, 'ms')
        this.recordMetric('页面加载时间', entry.loadEventEnd - entry.loadEventStart, 'ms')
        this.recordMetric('首次渲染时间', entry.responseEnd - entry.fetchStart, 'ms')
      }
    }
  }

  // 监控资源加载时间
  private observeResourceTiming(): void {
    if ('PerformanceObserver' in window) {
      const observer = new PerformanceObserver((list) => {
        list.getEntries().forEach((entry) => {
          if (entry.entryType === 'resource') {
            const resourceEntry = entry as PerformanceResourceTiming
            const loadTime = resourceEntry.responseEnd - resourceEntry.startTime
            
            this.recordMetric(`资源加载时间: ${resourceEntry.name}`, loadTime, 'ms')
          }
        })
      })
      
      observer.observe({ entryTypes: ['resource'] })
      this.observers.push(observer)
    }
  }

  // 监控最大内容绘制时间 (LCP)
  private observeLCP(): void {
    if ('PerformanceObserver' in window) {
      const observer = new PerformanceObserver((list) => {
        const entries = list.getEntries()
        const lastEntry = entries[entries.length - 1]
        
        this.recordMetric('最大内容绘制时间 (LCP)', lastEntry.startTime, 'ms')
      })
      
      try {
        observer.observe({ entryTypes: ['largest-contentful-paint'] })
        this.observers.push(observer)
      } catch (e) {
        // LCP 可能不被支持
      }
    }
  }

  // 监控首次输入延迟 (FID)
  private observeFID(): void {
    if ('PerformanceObserver' in window) {
      const observer = new PerformanceObserver((list) => {
        list.getEntries().forEach((entry) => {
          this.recordMetric('首次输入延迟 (FID)', entry.processingStart - entry.startTime, 'ms')
        })
      })
      
      try {
        observer.observe({ entryTypes: ['first-input'] })
        this.observers.push(observer)
      } catch (e) {
        // FID 可能不被支持
      }
    }
  }

  // 监控累积布局偏移 (CLS)
  private observeCLS(): void {
    if ('PerformanceObserver' in window) {
      let clsValue = 0
      
      const observer = new PerformanceObserver((list) => {
        list.getEntries().forEach((entry) => {
          if (!entry.hadRecentInput) {
            clsValue += (entry as any).value
            this.recordMetric('累积布局偏移 (CLS)', clsValue, 'score')
          }
        })
      })
      
      try {
        observer.observe({ entryTypes: ['layout-shift'] })
        this.observers.push(observer)
      } catch (e) {
        // CLS 可能不被支持
      }
    }
  }

  // 记录自定义性能指标
  recordMetric(name: string, value: number, unit: string): void {
    const metric: PerformanceMetric = {
      name,
      value,
      unit,
      timestamp: Date.now(),
    }
    
    this.metrics.push(metric)
    
    // 保持指标数量在合理范围内
    if (this.metrics.length > 100) {
      this.metrics = this.metrics.slice(-50)
    }
    
    // 在开发环境下输出性能指标
    if (import.meta.env.DEV) {
      console.log(`性能指标: ${name} = ${value}${unit}`)
    }
  }

  // 开始性能测量
  startMeasure(name: string): void {
    if ('performance' in window && 'mark' in performance) {
      performance.mark(`${name}-start`)
    }
  }

  // 结束性能测量
  endMeasure(name: string): number {
    if ('performance' in window && 'mark' in performance && 'measure' in performance) {
      const startMark = `${name}-start`
      const endMark = `${name}-end`
      
      performance.mark(endMark)
      performance.measure(name, startMark, endMark)
      
      const measures = performance.getEntriesByName(name, 'measure')
      if (measures.length > 0) {
        const duration = measures[measures.length - 1].duration
        this.recordMetric(name, duration, 'ms')
        return duration
      }
    }
    
    return 0
  }

  // 获取性能指标
  getMetrics(): PerformanceMetric[] {
    return [...this.metrics]
  }

  // 获取性能报告
  getPerformanceReport(): {
    metrics: PerformanceMetric[]
    summary: {
      averageLoadTime: number
      totalMetrics: number
      criticalMetrics: PerformanceMetric[]
    }
  } {
    const loadTimeMetrics = this.metrics.filter(m => m.name.includes('加载时间'))
    const averageLoadTime = loadTimeMetrics.length > 0 
      ? loadTimeMetrics.reduce((sum, m) => sum + m.value, 0) / loadTimeMetrics.length 
      : 0
    
    const criticalMetrics = this.metrics.filter(m => 
      m.name.includes('LCP') || 
      m.name.includes('FID') || 
      m.name.includes('CLS') ||
      m.value > 1000 // 超过1秒的指标
    )
    
    return {
      metrics: this.metrics,
      summary: {
        averageLoadTime,
        totalMetrics: this.metrics.length,
        criticalMetrics,
      },
    }
  }

  // 清理资源
  destroy(): void {
    this.observers.forEach(observer => observer.disconnect())
    this.observers = []
    this.metrics = []
  }
}

// 创建全局性能监控实例
export const performanceMonitor = PerformanceMonitor.getInstance()